/**
 * \brief  Server-side de-marshaller of region manager session interface
 * \author Christian Helmuth
 * \date   2006-07-11
 */

/*
 * Copyright (C) 2006-2009 Christian Helmuth
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#ifndef _INCLUDE__RM_SESSION__SERVER_H_
#define _INCLUDE__RM_SESSION__SERVER_H_

#include <base/server.h>
#include <rm_session/rm_session.h>
#include <base/printf.h>

namespace Genode {

	class Rm_session_server : public Server_object, public Rm_session
	{
		public:

			int dispatch(int op, Ipc_istream &is, Ipc_ostream &os)
			{
				switch (op) {

				case ATTACH:
					{
						Dataspace_capability ds;
						size_t               size = 0;
						off_t                offset = 0;
						bool                 use_local_addr = false;
						addr_t               local_addr = 0;

						/* read arguments */
						is >> ds >> size >> offset >> use_local_addr >> local_addr;

						/* execute function */
						try {
							os << attach(ds, size, offset, use_local_addr, local_addr);
							return 0;

						/* translate exception types to error codes */
						} catch (Invalid_dataspace e) {
							os << (void *)0;
							return -1;
						} catch (Region_conflict e) {
							os << (void *)0;
							return -2;
						}
					}

				case DETACH:
					{
						void *addr = 0;

						is >> addr;
						detach(addr);
						return 0;
					}

				case ADD_CLIENT:
					{
						Thread_capability thread, pager;

						is >> thread;
						try {
							pager = add_client(thread);
							os << pager;
							return 0;
						} catch (Invalid_thread) {
							os << Thread_capability();
							return -1;
						} catch (Out_of_memory) {
							os << Thread_capability();
							return -2;
						}
					}

				case FAULT_HANDLER:
					{
						Signal_receiver_capability handler;

						is >> handler;
						fault_handler(handler);

						return 0;
					}

				case STATE:
					{
						State result = state();
						os << result;
						return 0;
					}

				case DATASPACE:
					{
						Dataspace_capability result = dataspace();
						os << result;
						return 0;
					}


				default:
					PWRN("unknown opcode %d", op);
					return -1;
				}
			}
	};
}

#endif /* _INCLUDE__RM_SESSION__SERVER_H_ */
